package org.example.rzfx.service;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.rzfx.dto.AlarmHandleDTO;
import org.example.rzfx.entity.Alarm;
import org.example.rzfx.entity.AlarmRule;
import org.example.rzfx.entity.Log;
import org.example.rzfx.mapper.AlarmMapper;
import org.example.rzfx.mapper.AlarmRuleMapper;
import org.example.rzfx.mapper.LogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 告警服务
 */
@Service
public class AlarmService extends ServiceImpl<AlarmMapper, Alarm> {
    
    @Resource
    private AlarmRuleMapper alarmRuleMapper;
    
    @Resource
    private LogMapper logMapper;
    
    @Autowired(required = false)
    private JavaMailSender mailSender;
    
    /**
     * 检查告警规则并触发
     */
    public void checkAlarmRules() {
        // 查询所有启用的告警规则
        LambdaQueryWrapper<AlarmRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AlarmRule::getEnabled, 1);
        List<AlarmRule> rules = alarmRuleMapper.selectList(wrapper);
        
        for (AlarmRule rule : rules) {
            try {
                checkSingleRule(rule);
            } catch (Exception e) {
                log.error("检查告警规则失败: " + rule.getRuleName(), e);
            }
        }
    }
    
    /**
     * 检查单个告警规则
     */
    private void checkSingleRule(AlarmRule rule) {
        JSONObject condition = JSON.parseObject(rule.getConditionJson());
        
        // 获取时间窗口（分钟）
        int timeWindow = condition.getIntValue("timeWindow");
        LocalDateTime startTime = LocalDateTime.now().minusMinutes(timeWindow);
        LocalDateTime endTime = LocalDateTime.now();
        
        // 构建查询条件
        LambdaQueryWrapper<Log> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(Log::getTimestamp, startTime).le(Log::getTimestamp, endTime);
        
        // 日志级别
        if (condition.containsKey("logLevel")) {
            wrapper.eq(Log::getLogLevel, condition.getString("logLevel"));
        }
        
        // 系统类型
        if (condition.containsKey("systemType")) {
            wrapper.eq(Log::getSystemType, condition.getString("systemType"));
        }
        
        // 关键字
        if (condition.containsKey("keyword")) {
            wrapper.like(Log::getContent, condition.getString("keyword"));
        }
        
        // 统计数量
        long count = logMapper.selectCount(wrapper);
        int threshold = condition.getIntValue("threshold");
        
        // 判断是否触发告警
        if (count >= threshold) {
            triggerAlarm(rule, (int) count, startTime, endTime);
        }
    }
    
    /**
     * 触发告警
     */
    private void triggerAlarm(AlarmRule rule, int logCount, LocalDateTime startTime, LocalDateTime endTime) {
        // 创建告警记录
        Alarm alarm = new Alarm();
        alarm.setRuleId(rule.getId());
        alarm.setRuleName(rule.getRuleName());
        alarm.setLogCount(logCount);
        alarm.setAlarmContent(String.format("在%s至%s期间，触发了告警规则【%s】，共%d条日志符合条件",
            startTime, endTime, rule.getRuleName(), logCount));
        alarm.setAlarmTime(LocalDateTime.now());
        alarm.setStatus(0); // 未处理
        
        this.save(alarm);
        
        // 发送邮件通知
        if (rule.getNotifyEmail() != null && !rule.getNotifyEmail().isEmpty()) {
            sendAlarmEmail(rule, alarm);
        }
    }
    
    /**
     * 发送告警邮件
     */
    private void sendAlarmEmail(AlarmRule rule, Alarm alarm) {
        if (mailSender == null) {
            log.warn("邮件发送器未配置，跳过邮件发送");
            return;
        }
        
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(rule.getNotifyEmail().split(","));
            message.setSubject("【日志分析平台】告警通知 - " + rule.getRuleName());
            message.setText(alarm.getAlarmContent());
            
            mailSender.send(message);
        } catch (Exception e) {
            log.error("发送告警邮件失败", e);
        }
    }
    
    /**
     * 处理告警
     */
    public void handleAlarm(AlarmHandleDTO handleDTO) {
        Alarm alarm = this.getById(handleDTO.getAlarmId());
        if (alarm == null) {
            throw new RuntimeException("告警记录不存在");
        }
        
        if (alarm.getStatus() == 1) {
            throw new RuntimeException("告警已被处理");
        }
        
        Long userId = StpUtil.getLoginIdAsLong();
        alarm.setHandlerId(userId);
        alarm.setHandleTime(LocalDateTime.now());
        alarm.setStatus(1);
        alarm.setRemark(handleDTO.getRemark());
        
        this.updateById(alarm);
    }
    
    /**
     * 查询未处理告警
     */
    public List<Alarm> getUnhandledAlarms() {
        LambdaQueryWrapper<Alarm> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Alarm::getStatus, 0).orderByDesc(Alarm::getAlarmTime);
        return this.list(wrapper);
    }
}

